#include <linux/kernel.h>    
#include <linux/module.h>   
#include <linux/sched.h>   
#include <linux/mm_types.h> 

// 模块初始化函数，在模块加载时调用
static int __init stack_frame_info_init(void) {
    // 获取当前任务结构体
    struct task_struct *task = current;

    // 获取当前任务的用户栈起始地址
    unsigned long user_stack = task->mm->start_stack;

    // 定义变量以存储前一帧的基址和返回地址
    unsigned long prev_frame, return_address;

    // 内联汇编代码，获取当前栈帧（RBP）和返回地址
    asm volatile (
        "movq %%rbp, %0\n"   
        "movq 8(%0), %1\n"      
        : "=r" (prev_frame), "=r" (return_address)
        :                        
        : "memory"               
    );

    // 输出当前任务的名称和用户栈起始地址
    printk(KERN_INFO "Current Task: %s\n", task->comm);
    printk(KERN_INFO "User Stack Start: %lx\n", user_stack);

    // 输出前一个栈帧和返回地址的信息
    printk(KERN_INFO "Previous Stack Frame:\n");
    printk(KERN_INFO "Frame Address: %lx\n", prev_frame);
    printk(KERN_INFO "Return Address: %lx\n", return_address); 

    return 0; 
}

static void __exit stack_frame_info_exit(void) {
    printk(KERN_INFO "Module Unloaded.\n");
}

module_init(stack_frame_info_init);
module_exit(stack_frame_info_exit);

MODULE_LICENSE("GPL");            // 设置模块许可证为 GPL